contentprovider源码走读

获取ContentResolver

1
2
3
4
5
6
7
8
9
10
11
12
13
@Override
public ContentResolver getContentResolver() {
return mContentResolver;
}

//Context实例的创建
private ContextImpl(ContextImpl container, ActivityThread mainThread,
LoadedApk packageInfo, IBinder activityToken, UserHandle user, boolean restricted,
Display display, Configuration overrideConfiguration) {
...
mContentResolver = new ApplicationContentResolver(this, mainThread, user);
...
}

这里的ApplicationCOntentResolver继承自ContentResolver,ContentResolver是一个抽象类。它是ContextImpl的内部类。

query

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
//ContentResolver.java
public final Cursor query(final Uri uri, String[] projection,
String selection, String[] selectionArgs, String sortOrder,
CancellationSignal cancellationSignal) {
//先根据uri获取到ICP,ICP是ContentProvider的binder接口,继承自IInterface,这里获取unstable类型的
IContentProvider unstableProvider = acquireUnstableProvider(uri);
if (unstableProvider == null) {
return null;
}
IContentProvider stableProvider = null;
Cursor qCursor = null;
try {
long startTime = SystemClock.uptimeMillis();

ICancellationSignal remoteCancellationSignal = null;
if (cancellationSignal != null) {
cancellationSignal.throwIfCanceled();
remoteCancellationSignal = unstableProvider.createCancellationSignal();
cancellationSignal.setRemote(remoteCancellationSignal);
}
try {
//通过ICP查询,这里涉及到Binder调用
qCursor = unstableProvider.query(mPackageName, uri, projection,
selection, selectionArgs, sortOrder, remoteCancellationSignal);
} catch (DeadObjectException e) {
//远程进程死亡,负责清理unstable的ICP
unstableProviderDied(unstableProvider);
//随后创建stable的ICP
stableProvider = acquireProvider(uri);
if (stableProvider == null) {
return null;
}
//再次进行查询,取到Cursor
qCursor = stableProvider.query(mPackageName, uri, projection,
selection, selectionArgs, sortOrder, remoteCancellationSignal);
}
if (qCursor == null) {
return null;
}

// Force query execution. Might fail and throw a runtime exception here.
qCursor.getCount();
long durationMillis = SystemClock.uptimeMillis() - startTime;
maybeLogQueryToEventLog(durationMillis, uri, projection, selection, sortOrder);

// Wrap the cursor object into CursorWrapperInner object.
CursorWrapperInner wrapper = new CursorWrapperInner(qCursor,
stableProvider != null ? stableProvider : acquireProvider(uri));
stableProvider = null;
qCursor = null;
return wrapper;
} catch (RemoteException e) {
// Arbitrary and not worth documenting, as Activity
// Manager will kill this process shortly anyway.
return null;
} finally {
if (qCursor != null) {
qCursor.close();
}
if (cancellationSignal != null) {
cancellationSignal.setRemote(null);
}
if (unstableProvider != null) {
releaseUnstableProvider(unstableProvider);
}
if (stableProvider != null) {
releaseProvider(stableProvider);
}
}
}

以CursorWrapperInner返回,它实现了Cursor接口。这里unstable和stable的区别在于,unstable的ContentProvider不会因为其远程服务进程的死亡而导致app被杀掉,而stable会。

1
2
3
4
5
6
7
8
9
10
11
//ContentResolver.java
public final IContentProvider acquireUnstableProvider(Uri uri) {
if (!SCHEME_CONTENT.equals(uri.getScheme())) {
return null;
}
String auth = uri.getAuthority();
if (auth != null) {
return acquireUnstableProvider(mContext, uri.getAuthority());
}
return null;
}

这里acquireUnstableProvider是个抽象方法,那么应该在其子类ApplicationContentResolver中实现。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
//ApplicationContentResolver.java
@Override
protected IContentProvider acquireUnstableProvider(Context c, String auth) {
return mMainThread.acquireProvider(c, auth, mUser.getIdentifier(), false);
}

//ActivityThread.java
public final IContentProvider acquireProvider(
Context c, String auth, int userId, boolean stable) {
final IContentProvider provider = acquireExistingProvider(c, auth, userId, stable);
if (provider != null) {
return provider;
}
IActivityManager.ContentProviderHolder holder = null;
try {
//这里阻塞等待直到获取Provider代理,如果Provider未启动,则先启动
holder = ActivityManagerNative.getDefault().getContentProvider(
getApplicationThread(), auth, userId, stable);
} catch (RemoteException ex) {
}
if (holder == null) {
Slog.e(TAG, "Failed to find provider info for " + auth);
return null;
}

// Install provider will increment the reference count for us, and break
// any ties in the race.
holder = installProvider(c, holder, holder.info,
true /*noisy*/, holder.noReleaseNeeded, stable);
return holder.provider;
}

这里我们可以看到它ICP先试通过acquireExistingProvider来获取,如果取到就直接返回,否则就需要通过AMS的getContentProvider来取到的,它返回一个IActivityManager.ContentProviderHolder成员holder,其中的provider就是ICP的binder代理接口。那么acquireExistingProvider大概就是从缓存里取吧。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
//ActivityThread.java
public final IContentProvider acquireExistingProvider(
Context c, String auth, int userId, boolean stable) {
synchronized (mProviderMap) {
final ProviderKey key = new ProviderKey(auth, userId);//以auth和userid构造一个key
final ProviderClientRecord pr = mProviderMap.get(key);//通过该key取到ProviderClientRecord
if (pr == null) {
return null;
}

IContentProvider provider = pr.mProvider;//从ProviderClientRecord就可以取到ICP的binder代理接口
IBinder jBinder = provider.asBinder();
if (!jBinder.isBinderAlive()) {//判断binder server是否还活着
// The hosting process of the provider has died; we can't
// use this one.
Log.i(TAG, "Acquiring provider " + auth + " for user " + userId
+ ": existing object's process dead");
handleUnstableProviderDiedLocked(jBinder, true);
return null;
}

// Only increment the ref count if we have one. If we don't then the
// provider is not reference counted and never needs to be released.
ProviderRefCount prc = mProviderRefCountMap.get(jBinder);
if (prc != null) {
incProviderRefLocked(prc, stable);//增加该provider的引用计数
}
return provider;
}
}

其中mProviderMap中记录的是本进程的ContentProvider,它再应用启动时候就进行了初始化,这样如果是当前应用使用自身的ContentProvider,就不需要再去AMS中查找了,直接从这里就可以取到。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
//ActivityManagerService.java
public final ContentProviderHolder getContentProvider(
IApplicationThread caller, String name, int userId, boolean stable) {
……
userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
false, true, "getContentProvider", null);
return getContentProviderImpl(caller, name, null, stable, userId);
}

private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
String name, IBinder token, boolean stable, int userId) {
ContentProviderRecord cpr;
ContentProviderConnection conn = null;
ProviderInfo cpi = null;

synchronized(this) {
ProcessRecord r = getRecordForAppLocked(caller);
...
cpr = mProviderMap.getProviderByName(name, userId);//查看这个contentProvider是否已经有记录

boolean providerRunning = cpr != null;
if (providerRunning) {//content provider已经存在

if (r != null && cpr.canRunHere(r)) {
//Content provider被允许运行在调用者进程,这样让调用者自己实例化一个content provider实例即可
ContentProviderHolder holder = cpr.newHolder(null);
holder.provider = null;
return holder;
}
}

……
//content provider没在运行
if (!providerRunning) {
……
ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
cpr = mProviderMap.getProviderByClass(comp, userId);
final boolean firstClass = cpr == null;
if (firstClass) {
ApplicationInfo ai =
AppGlobals.getPackageManager().
getApplicationInfo(
cpi.applicationInfo.packageName,
STOCK_PM_FLAGS, userId);
ai = getAppInfoForUser(ai, userId);
//为content provider创建record
cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
}

if (r != null && cpr.canRunHere(r)) {
return cpr.newHolder(null);
}

final int N = mLaunchingProviders.size();
int i;
for (i=0; i<N; i++) {
if (mLaunchingProviders.get(i) == cpr) {
break;
}
}

if (i >= N) {
final long origId = Binder.clearCallingIdentity();

try {
// Content provider is now in use, its package can't be stopped.
try {
AppGlobals.getPackageManager().setPackageStoppedState(
cpr.appInfo.packageName, false, userId);
} catch (RemoteException e) {
} catch (IllegalArgumentException e) {
Slog.w(TAG, "Failed trying to unstop package "
+ cpr.appInfo.packageName + ": " + e);
}

// Use existing process if already started
ProcessRecord proc = getProcessRecordLocked(
cpi.processName, cpr.appInfo.uid, false);//获取进程信息
if (proc != null && proc.thread != null) {//如果所在进程已经启动
proc.pubProviders.put(cpi.name, cpr);
try {
//启动content provider并发布
proc.thread.scheduleInstallProvider(cpi);
} catch (RemoteException e) {
}
} else {
//启动conent provider的目标进程
proc = startProcessLocked(cpi.processName,
cpr.appInfo, false, 0, "content provider",
new ComponentName(cpi.applicationInfo.packageName,
cpi.name), false, false, false);
……
}
cpr.launchingApp = proc;
mLaunchingProviders.add(cpr);
} finally {
Binder.restoreCallingIdentity(origId);
}
}

// Make sure the provider is published (the same provider class
// may be published under multiple names).
if (firstClass) {
mProviderMap.putProviderByClass(comp, cpr);
}

mProviderMap.putProviderByName(name, cpr);
conn = incProviderCountLocked(r, cpr, token, stable);
}
}

//循环等待,直到provider发布完成才会退出循环.
synchronized (cpr) {
while (cpr.provider == null) {
...
cpr.wait();
...
}
}
}

Provoider的install流程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
public void handleInstallProvider(ProviderInfo info) {
installContentProviders(mInitialApplication, Lists.newArrayList(info));
}

private void installContentProviders(
Context context, List<ProviderInfo> providers) {
final ArrayList<IActivityManager.ContentProviderHolder> results =
new ArrayList<IActivityManager.ContentProviderHolder>();

for (ProviderInfo cpi : providers) {
if (DEBUG_PROVIDER) {
StringBuilder buf = new StringBuilder(128);
buf.append("Pub ");
buf.append(cpi.authority);
buf.append(": ");
buf.append(cpi.name);
}
IActivityManager.ContentProviderHolder cph = installProvider(context, null, cpi,
false /*noisy*/, true /*noReleaseNeeded*/, true /*stable*/);
if (cph != null) {
cph.noReleaseNeeded = true;
results.add(cph);
}
}

try {
//发布该provider
ActivityManagerNative.getDefault().publishContentProviders(
getApplicationThread(), results);
} catch (RemoteException ex) {
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
// ActivityThread.java
private IActivityManager.ContentProviderHolder installProvider(Context context,
IActivityManager.ContentProviderHolder holder, ProviderInfo info,
boolean noisy, boolean noReleaseNeeded, boolean stable) {
ContentProvider localProvider = null;
IContentProvider provider;
if (holder == null || holder.provider == null) {
try{

final java.lang.ClassLoader cl = c.getClassLoader();
localProvider = (ContentProvider)cl.
loadClass(info.name).newInstance();
provider = localProvider.getIContentProvider();
localProvider.attachInfo(c, info);

}
}

synchronized (mProviderMap) {
IBinder jBinder = provider.asBinder();
if (localProvider != null) {
ComponentName cname = new ComponentName(info.packageName, info.name);
ProviderClientRecord pr = mLocalProvidersByName.get(cname);
if (pr != null) {
provider = pr.mProvider;
}else{
holder = new IActivityManager.ContentProviderHolder(info);
holder.provider = provider;
holder.noReleaseNeeded = true;
pr = installProviderAuthoritiesLocked(provider, localProvider, holder);
mLocalProviders.put(jBinder, pr);
mLocalProvidersByName.put(cname, pr);
}
retHolder = pr.mHolder;
}else{
...
}
}

return retHolder;
}

该过程主要创建ContentProvider实例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
//ActivityManagerService.java
public final void publishContentProviders(IApplicationThread caller,
List<ContentProviderHolder> providers) {
if (providers == null) {
return;
}

synchronized (this) {
final ProcessRecord r = getRecordForAppLocked(caller);
...
final long origId = Binder.clearCallingIdentity();

final int N = providers.size();
for (int i=0; i<N; i++) {
ContentProviderHolder src = providers.get(i);
if (src == null || src.info == null || src.provider == null) {
continue;
}
ContentProviderRecord dst = r.pubProviders.get(src.info.name);
if (dst != null) {
ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
mProviderMap.putProviderByClass(comp, dst);//将实例添加到mProviderMap
String names[] = dst.info.authority.split(";");
for (int j = 0; j < names.length; j++) {
mProviderMap.putProviderByName(names[j], dst);
}

int NL = mLaunchingProviders.size();
int j;
for (j=0; j<NL; j++) {
if (mLaunchingProviders.get(j) == dst) {
mLaunchingProviders.remove(j);
j--;
NL--;
}
}
synchronized (dst) {
dst.provider = src.provider;
dst.proc = r;
dst.notifyAll();
}
updateOomAdjLocked(r);
}
}
Binder.restoreCallingIdentity(origId);
}
}
坚持原创技术分享,您的支持将鼓励我继续创作!